<?php

namespace app\api\controller;

use app\api\model\RushGoods;
use app\api\model\RushOrder;
use app\api\model\RushStatistic;
use app\api\model\RushTime;
use app\common\controller\Api;
use app\common\model\User;
use DateTime;
use EasyWeChat\Foundation\Application;
use think\Cache;
use think\Db;
use think\Exception;
use think\exception\PDOException;

/**
 * 抢购
 */
class Rush extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = '*';

    /**
     * @ApiTitle    (首页)
     * @ApiMethod   (GET)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiReturn   ({
        "code": 1,
        "msg": "",
        "time": "1652230182",
        "data": [{ //列表
            "id": 1, //ID
            "name": "狂欢上午场", //名称
            "starttime": "10:30", //开始时间
            "endtime": "11:30", //结束时间
            "tip": "上午场", //提示
        }]
    })
     */
    public function index()
    {
        $list = RushTime::where('status','1')
            ->field('id,name,starttime,endtime,tip,status')
            ->select();
        foreach($list as $v){
            $v['starttime'] = substr($v['starttime'],0,-3);
            $v['endtime'] = substr($v['endtime'],0,-3);
        }
        $this->success('', $list);
    }

    /**
     * @ApiTitle    (商品列表)
     * @ApiMethod   (GET)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name="rush_time_id", type="integer", required=true, description="抢购场次ID")
     * @ApiParams   (name="page", type="integer", required=false, description="分页页码")
     * @ApiReturn   ({
        "code": 1,
        "msg": "",
        "time": "1652230261",
        "data": {
            "total": 2, //数据总数
            "per_page": 15, //每页条数
            "current_page": 1, //当前分页
            "last_page": 1, //总页数
            "data": [{ //列表
                "id": 1, //ID
                "image": "http://petsdemo.qiniu.brofirst.cn/uploads/20220508/13cb1b8e54988cbb3710cc79897f0096.jpg", //图片
                "name": "商品一", //名称
                "current_price": "7000.00", //当前价格
                "status": "1", //商品状态:0=下架,1=上架
                "status_text": ""
            }]
        }
    })
     */
    public function goodsList()
    {
        $rush_time_id = $this->request->param('rush_time_id');
        empty($rush_time_id) && $this->error('请选择抢购场次');
        $rushtime = RushTime::where('id',$rush_time_id)->field('starttime,endtime,status')->find();
        empty($rushtime) && $this->error('抢购场次不存在');
        $rushtime['status'] == '0' && $this->error('抢购场次未开启');
        $rush_starttime = strtotime(date('Y-m-d').' '.$rushtime['starttime'])-1800;
        time() < $rush_starttime && $this->error('只能提前半小时进场');
        $rush_endtime = strtotime(date('Y-m-d').' '.$rushtime['endtime']);
        time() > $rush_endtime && $this->error('狂欢场已结束了',[],3);
        //统计进场数据
        $this->getRushStatistic($rush_time_id,$this->auth->id);
        $where = [
            'a.time_id' => $rush_time_id,
            'b.order_status' => ['neq','4'],
        ];
        $list = RushGoods::alias('a')
            ->join('rush_order b','b.id = a.current_order_id')
            ->where($where)
            ->field('a.id,a.image,a.name,a.current_price,a.status')
            ->order('a.status desc,a.weigh desc')
            ->paginate(10);
        $this->success('',$list);
    }

    /**
     * 统计进场数据
     */
    private function getRushStatistic($rush_time_id,$user_id){
        $where = [
            'time_id' => $rush_time_id,
            'user_id' => $user_id
        ];
        $has = RushStatistic::where($where)->whereTime('updatetime','today')->find();
        if($has){
            $has->save(['updatetime'=>time()]);
        }else{
            RushStatistic::create($where);
        }
    }

    /**
     * @ApiTitle    (商品详情)
     * @ApiMethod   (GET)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name=goods_id, type=integer, required=true, description="商品ID")
     * @ApiReturn   ({
        "code": 1,
        "msg": "",
        "time": "1652232148",
        "data": {
            "id": 1, //商品ID
            "images": [ //组图
                "http://petsdemo.qiniu.brofirst.cn/uploads/20220508/13cb1b8e54988cbb3710cc79897f0096.jpg"
            ],
            "name": "商品一", //商品名称
            "current_price": "7000.00", //当前价格
            "content": "123", //详情描述
            "seller_id": 1000,
            "time_id": 1,
            "status": "1", //商品状态:0=下架,1=上架
            "seller": { //藏品归属人
                "id": 1000, //ID
                "nickname": "Xue", //昵称
                "url": "/u/1000"
            },
            "countdown": 0, //倒计时
            "is_vip": 0, //是否会员:0=否,1=是
            "status_text": ""
        }
    })
     */
    public function goodsDetail()
    {
        $goods_id = $this->request->param('goods_id');
        empty($goods_id) && $this->error('请选择商品');
        $goods = RushGoods::where('id',$goods_id)->field('id,images,name,current_price,content,seller_id,time_id,status')->find();
        $goods['seller'] = User::where('id',$goods['seller_id'])->field('id,nickname')->find();
        $rush_time = RushTime::where('id',$goods['time_id'])->field('id,starttime')->find();
        $stattime = strtotime(date('Y-m-d').' '.$rush_time['starttime']);
        $goods['countdown'] = time() >= $stattime ? 0 : ($stattime - time());
        $goods['is_vip'] = User::where('id',$this->auth->id)->value('is_vip');
        $this->success('',$goods);
    }

    /**
     * @ApiTitle    (抢购)
     * @ApiMethod   (GET)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name=goods_id, type=integer, required=true, description="商品ID")
     * @ApiReturn   ({
        "code": 1,
        "msg": "",
        "time": "1652232148",
        "data": {
            "notice": 1,//注意:1=很遗憾您没有抢到藏品,2=狂欢场已结束了,3=不可抢购自己的商品,4=真正开场前，会员只可购买一件商品
        }
    })
     */
    public function rush()
    {
        $goods_id = $this->request->param('goods_id');
        empty($goods_id) && $this->error('请选择商品');
        $goods = RushGoods::get($goods_id);
        empty($goods) && $this->error('商品不存在');
        $user = $this->auth->getUser();
        $user['id'] == $goods['seller_id'] && $this->error('不可抢购自己的藏品',['notice'=>3]);
        //抢购时间判断
        $rushtime = $goods['rushtime'];
        $rush_starttime = strtotime(date('Y-m-d').' '.$rushtime['starttime']);
        //会员可提前一分钟抢购
        if($user['is_vip'] == 1){
            $rush_starttime = $rush_starttime-600;
        }
        $current_time = time();
        $current_time < $rush_starttime && $this->error('抢购还未开始，请耐心等待');
        $rush_endtime = strtotime(date('Y-m-d').' '.$rushtime['endtime']);
        $current_time > $rush_endtime && $this->error('狂欢场已结束了',['notice'=>2]);
        //用缓存3秒，防止并发抢购
        Cache::get($goods_id) && $this->error('很遗憾您没有抢到藏品',['notice'=>1]);
        $goods['status'] == '0' && $this->error('很遗憾您没有抢到藏品',['notice'=>1]);
        //真正开场前，会员只可购买一件商品
        if($user['is_vip'] == 1){
            $cache_name = $user['id'].'_'.$goods['time_id'];
            Cache::get($cache_name) && $this->error('真正开场前，会员只可购买一件商品',['notice'=>4]);
            //过滤有效期为0的永久缓存
            Cache::set($cache_name,'1',strtotime($rushtime['starttime']) - $current_time ?: -1);
        }
        Cache::set($goods_id,'1',3);
        Db::startTrans();
        try {

            //抢单订单状态改为：未支付
            RushOrder::where('id',$goods['current_order_id'])->update([
                'buyer_id' => $user['id'],
                'order_status' => '0',
                'rushtime' => time(), //抢购时间
            ]);

            //商品临时下架
            $goods->save(['status' => '0']);

            //删除重复的队列记录，（订单逻辑不同于其他项目，所以需要删除）
            $payload = json_encode([
                'job' => "\\app\\api\\job\\RushOrderAutoOper@autoCancel",
                'data' => ['order_id'=>$goods['current_order_id']],
            ]);
            Db::name('jobs')->where('payload',$payload)->delete();
            // 买家超过50分钟未支付确认的，订单自动变为原来的状态。
            $close_minue = 50;
            \think\Queue::later(($close_minue * 60), '\app\api\job\RushOrderAutoOper@autoCancel', ['order_id' => $goods['current_order_id']], 'rushbuy');

            Db::commit();
        }catch (PDOException $e){
            Db::rollback();
            $this->error($e->getMessage());
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success();
    }
}
